package model

import (
	"context"
	"fmt"
	"os"

	go_service "gitee.com/liumou_site/go-service"
)

// IsServiceRegistered 检测SSH Guardian服务是否已注册
// 该函数会检查ssh-guardian服务是否存在于systemd中
//
// 返回值:
//   - bool: 如果服务已注册返回true，否则返回false
func IsServiceRegistered() bool {
	// ctx := context.Background()
	service, err := go_service.NewService("ssh-guardian", "", "")
	if err != nil {
		GetLanguageManager().Debug("创建服务实例以进行检测失败: ", "Failed to create service instance for detection: ", err)
		return false
	}

	// 检查服务是否存在
	if service.IsServiceExist() {
		GetLanguageManager().Debug("SSH Guardian 服务已注册", "SSH Guardian service is registered")
		return true
	}

	GetLanguageManager().Debug("SSH Guardian 服务未注册", "SSH Guardian service is not registered")
	return false
}

// CreateSshGuardianService 使用 go-service 库创建或更新 ssh-guardian 服务。
// 该函数负责创建 systemd 服务，并根据 init 参数决定是否需要覆盖已有的服务。
// 在创建服务之前，会检测并停止正在运行的相关服务，清理旧的配置文件，并将当前程序复制到指定位置。
// 最后，该函数会启用并启动服务。
//
// 权限边界：
//   - 该函数只能管理ssh-guardian自身服务，不能管理sshd服务
//   - 仅在服务注册流程中被调用
//   - 通过调用stopAndCleanupOldServices清理旧版本服务和配置文件
//
// 参数:
//   - i: Info结构体指针，包含服务配置信息
//
// 返回值:
//   - error: 如果过程中发生错误，则返回错误信息；否则返回 nil。
func CreateSshGuardianService(i *Info) error {
	// 获取语言管理器
	langManager := GetLanguageManager()

	if i.Debug {
		langManager.Debug("正在创建SSH Guardian服务", "CreateSshGuardianService")
	}

	// 检测并停止正在运行的相关服务
	err := stopAndCleanupOldServices(i)
	if err != nil {
		return err
	}

	// 清理旧的配置文件和ssh-guardian相关服务
	// 注意：仅清理ssh-guardian自身服务，不涉及sshd服务
	oldConfigPaths := []string{
		"/etc/systemd/system/com.liumou.ssh.service",
		"/etc/systemd/system/cls.service",
		"/etc/systemd/system/xc-ssh.service",
		"/etc/systemd/system/ssh-guardian.service",
		"/usr/lib/systemd/system/com.liumou.ssh.service",
		"/usr/lib/systemd/system/cls.service",
		"/usr/lib/systemd/system/xc-ssh.service",
		"/usr/lib/systemd/system/ssh-guardian.service",
	}
	err = cleanupOldSSHConfig(oldConfigPaths)
	if err != nil {
		return err
	}

	// 获取程序路径并复制到 /usr/sbin/ssh-guardian
	programPath, err := os.Executable()
	if err != nil {
		langManager.Error("无法获取程序路径:", "Unable to obtain program path:", err)
		return err
	}
	if programPath != "/usr/sbin/ssh-guardian" {
		i.Cmd.RunShell("cp -rf", programPath, "/usr/sbin/ssh-guardian")
		if i.Cmd.Err != nil {
			langManager.Error("无法复制程序到/usr/sbin/ssh-guardian:", "Unable to copy program to /usr/sbin/ssh-guardian:", i.Cmd.Err)
			return i.Cmd.Err
		}
	}

	// 使用 go-service 库创建 SSH Guardian 服务
	ctx := context.Background()
	service, err := go_service.NewService("ssh-guardian", "SSH Guardian Service", "/usr/sbin/ssh-guardian")
	if err != nil {
		langManager.Error("创建服务实例失败:", "Failed to create service instance:", err)
		return fmt.Errorf("创建服务实例失败: %v", err)
	}

	// 设置服务参数
	var args []string
	args = append(args, "-port", fmt.Sprintf("%d", i.Port))

	// 根据语言设置添加语言参数
	if i.China {
		args = append(args, "-lang", "zh")
	} else {
		args = append(args, "-lang", "en")
	}

	service.SetArgs(args)

	// 在创建服务之前，确保 systemd 守护进程已重载
	// 使用 systemctl daemon-reload 命令重载 systemd
	i.Cmd.RunShell("systemctl", "daemon-reload")
	if i.Cmd.Err != nil {
		langManager.Warn("重载systemd守护进程失败:", "Failed to reload systemd daemon:", i.Cmd.Err)
		// 继续执行，这不是致命错误
	}

	// 配置服务参数
	service.SetRestartPolicy("always")
	service.SetUser("root")
	service.SetAutoStart(true)
	service.SetWantedBy("multi-user.target")
	service.SetWorkingDir("/tmp/")

	// 检查服务是否存在，并根据 init 参数决定是否继续
	if service.IsServiceExist() {
		if !i.Init {
			if i.Debug {
				langManager.Debug("服务已存在，跳过创建", "Service already exists, skip")
			}
			return nil
		} else {
			langManager.Info("检测到服务已存在，将覆盖它", "Detected that the service already exists, will overwrite it")
			// 如果服务已存在且需要覆盖，使用systemctl命令停止并禁用服务
			i.Cmd.RunShell("systemctl", "stop", "ssh-guardian")
			if i.Cmd.Err != nil {
				langManager.Warn("停止旧服务失败，继续创建:", "Failed to stop old service, continue creating:", i.Cmd.Err)
			}

			i.Cmd.RunShell("systemctl", "disable", "ssh-guardian")
			if i.Cmd.Err != nil {
				langManager.Warn("禁用旧服务失败，继续创建:", "Failed to disable old service, continue creating:", i.Cmd.Err)
			}

			// 重新加载systemd配置
			i.Cmd.RunShell("systemctl", "daemon-reload")
			if i.Cmd.Err != nil {
				langManager.Warn("重载systemd守护进程失败:", "Failed to reload systemd daemon:", i.Cmd.Err)
			}

			// 显式删除服务文件，确保可以重新创建
			serviceFiles := []string{
				"/etc/systemd/system/ssh-guardian.service",
				"/usr/lib/systemd/system/ssh-guardian.service",
			}
			for _, file := range serviceFiles {
				if _, err = os.Stat(file); err == nil {
					i.Cmd.RunShell("rm", "-f", file)
					if i.Cmd.Err != nil {
						langManager.Warn("删除服务文件失败:", "Failed to remove service file:", i.Cmd.Err)
					}
				}
			}

			// 再次重载systemd配置
			i.Cmd.RunShell("systemctl", "daemon-reload")
			if i.Cmd.Err != nil {
				langManager.Warn("重载systemd守护进程失败:", "Failed to reload systemd daemon:", i.Cmd.Err)
			}
		}
	}

	// 创建并启用服务
	err = service.CreateService(ctx)
	if err != nil {
		GetLanguageManager().Error("创建服务失败: ", "Failed to create service: ", err)
		return fmt.Errorf("创建服务失败: %v", err)
	}

	err = service.EnableService(ctx)
	if err != nil {
		GetLanguageManager().Error("启用服务失败: ", "Failed to enable service: ", err)
		return fmt.Errorf("启用服务失败: %v", err)
	}

	// 启动服务
	err = service.Start(ctx)
	if err != nil {
		langManager.Error("启动服务失败:", "Unable to start service:", err)
		return fmt.Errorf("启动服务失败: %v", err)
	}

	langManager.Info("SSH Guardian服务创建、启用和启动成功", "SSH Guardian service created, enabled and started successfully")

	// 显示服务管理命令
	fmt.Println("\n=== 服务管理命令 ===")
	fmt.Println("查看服务状态: systemctl status ssh-guardian")
	fmt.Println("停止服务: systemctl stop ssh-guardian")
	fmt.Println("重启服务: systemctl restart ssh-guardian")
	fmt.Println("禁用服务: systemctl disable ssh-guardian")
	fmt.Println("启用服务: systemctl enable ssh-guardian")
	fmt.Println("查看服务日志: journalctl -u ssh-guardian -f")
	fmt.Println("===================")

	// 获取并显示服务文件内容
	serviceFilePath := "/etc/systemd/system/ssh-guardian.service"
	if _, err := os.Stat(serviceFilePath); err == nil {
		if i.China {
			fmt.Println("\n=== 服务文件内容 ===")
		} else {
			fmt.Println("\n=== Service File Content ===")
		}

		content, err := os.ReadFile(serviceFilePath)
		if err == nil {
			fmt.Println(string(content))
		} else {
			if i.China {
				fmt.Printf("读取服务文件失败: %v\n", err)
			} else {
				fmt.Printf("Failed to read service file: %v\n", err)
			}
		}
		fmt.Println("===================")
	}

	// 只有在服务是新创建或重新创建的情况下才退出当前进程
	// 如果服务已存在且不需要重新创建，则继续执行监控循环
	if service.IsServiceExist() && !i.Init {
		// 服务已存在且不需要重新创建，继续执行监控循环
		return nil
	}
	// 服务是新创建或重新创建的，设置退出标志
	i.Exit = true
	return nil
}
